package com.topisv.tms.tools;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.topisv.tms.entity.Area;
import com.topisv.tms.entity.CheckInOrOut;
import com.topisv.tms.entity.CheckInOrOutItem;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.OrderMergeConfig;
import com.topisv.tms.entity.stock.instorage.InstorageBill;
import com.topisv.tms.entity.stock.instorage.InstorageCountItem;
import com.topisv.tms.entity.stock.instorage.MDHouseConfig;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillBoxPre;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillItemPre;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.OrderMergeConfigDao;
import com.topisv.tms.repository.md.MDHouseConfigDao;
import com.topisv.tms.rest.entity.md.request.AnntoOrderDetail;
import com.topisv.tms.rest.entity.md.request.AnntoOrderRequestBody;
import com.topisv.tms.rest.entity.md.request.OrderConfirmDetail;
import com.topisv.tms.rest.entity.md.request.OrderConfirmRequestBody;
import com.topisv.tms.rest.entity.md.request.TransferBody;
import com.topisv.tms.rest.entity.md.request.TransferBodyContent;
import com.topisv.tms.rest.entity.md.request.TransferData;
import com.topisv.tms.rest.entity.md.request.TransferSubject;
import com.topisv.tms.service.AreaService;
import com.topisv.tms.service.vo.invoice.InvoiceRequest;
import com.topisv.tms.service.vo.invoice.MDParam;
import com.topisv.tms.utils.BlankUtil;
import com.topisv.tms.utils.DateUtils;
import com.topisv.tms.utils.EdiOrderUtil;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.MDDocumentType;
import com.topisv.tms.utils.enums.MDGoodsStatus;
import com.topisv.tms.utils.enums.MDOrderType;
import com.topisv.tms.utils.enums.PYOrderType;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.utils.rule.TMSTransportRule;
import com.topisv.tms.utils.vo.PreInstorageVo;

/**
 * 对象转换工具类
 *  Date          Author       Version       Description
 * ----------------------------------------------------------
 *  2015-1-8      CC            1.0           Create
 */
@Component
public class TransferHelper {
	private static Logger logger = LoggerFactory.getLogger("TransferHelper");
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private OrderMergeConfigDao orderMergeConfigDao;
	@Autowired
	private MDHouseConfigDao mdHouseConfigDao;
	@Autowired
	private AreaService areaService;

	/**
	 * 订单接口
	 * @param data
	 * @return List<EdiOrder>
	 */
	public List<EdiOrder> transferFromMidea4Order(TransferData data) {
		if (MDDocumentType.ORDER.getSubjectType().equals(data.getTransferSubject().getDocumentType())) {
			return transferFromOrderSale(AnntoOrderRequestBody.class.cast(getTransferBodyContent(data)));
		}
		return null;
	}
	
	/**
	 * 返厂出库
	 * @param data
	 * @return List<EdiOrder>
	 */
	public EdiOrder transferFromMidea4Reback(TransferData data) {
		if (MDDocumentType.ORDER.getSubjectType().equals(data.getTransferSubject().getDocumentType())) {
			return transferFromReback(AnntoOrderRequestBody.class.cast(getTransferBodyContent(data)));
		}
		return null;
	}
	
	/**
	 * 拆分订单、每个SKU拆分为1单。赠品与任意非赠品合并为1单
	 * @param anntoOrder
	 * @return List<EdiOrder>
	 */
	public EdiOrder transferFromReback(AnntoOrderRequestBody anntoOrder) {
		List<AnntoOrderDetail> orderDetails = anntoOrder.getOrderDetails();
		Collections.sort(orderDetails, new Comparator<AnntoOrderDetail>() {
			@Override
			public int compare(AnntoOrderDetail item1, AnntoOrderDetail item2) {
				return item1.getPrice() == null ? 1 : item2.getPrice() == null ? -1 : item2.getPrice().compareTo(item1.getPrice());
			}
		});
		
		EdiOrder order = transfer2EdiOrder(anntoOrder, mdHouseConfigDao.loadByMdWarehouseCode(anntoOrder.getPlant()), areaService.getTopAreaBy(anntoOrder.getProv(), anntoOrder.getCity()));
		List<EdiOrderItem> orderItems = new ArrayList<EdiOrderItem>();
		boolean priGtZero = false;
		for (int i = 0; i < orderDetails.size(); i++) {
			AnntoOrderDetail orderDetail = orderDetails.get(i);
			// 订单下发的时候MD集团编码 对应派友的bar字段。
			EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, orderDetail.getCustGoodsCode());
			if (goodsSku == null) {
				throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { orderDetail.getCustGoodsCode() });
			}
			EdiOrderItem item = transferFromOrderSale(orderDetail, goodsSku);
			item.setQty(orderDetail.getPlanQty());
			priGtZero = priGtZero || (item.getPri() != null && item.getPri() > 0);
			orderItems.add(item);
		}
		order.setIsInvoice(order.getIsInvoice() && priGtZero);
		order.setSkulst(orderItems);
		
		return order;
	}

	/**
	 * 退货入库
	 * 模拟预约入库流程
	 * @param data
	 * @return List<EdiOrder>
	 */
	public PreInstorageVo transferFromMidea4Back(TransferData data) {
		if (MDDocumentType.ORDER.getSubjectType().equals(data.getTransferSubject().getDocumentType())) {
			return transferFromOrderBack(AnntoOrderRequestBody.class.cast(getTransferBodyContent(data)));
		}
		return null;
	}

	/**
	 * 预约入库
	 * @param data
	 * @return PreInstorageVo
	 */
	public PreInstorageVo transferFromOrderPurChase(TransferData data) {
		if (MDDocumentType.ORDER.getSubjectType().equals(data.getTransferSubject().getDocumentType())) {
			return transferFromOrderPurChase(AnntoOrderRequestBody.class.cast(getTransferBodyContent(data)));
		}
		return null;
	}
	
	/**
	 * 盘点出入库
	 * @param data
	 * @return CheckInOrOut
	 */
	public CheckInOrOut transferFromMidea4CheckInOrOut(TransferData data) {
		if (MDDocumentType.ORDER.getSubjectType().equals(data.getTransferSubject().getDocumentType())) {
			return transferFromCheckInOrOut(AnntoOrderRequestBody.class.cast(getTransferBodyContent(data)));
		}
		return null;
	}
	
	
	public static TransferBodyContent getTransferBodyContent(TransferData data) {
		TransferBody transferBody = data.getTransferBody();
		TransferBodyContent bodyContent = null;
		if (transferBody != null) {
			bodyContent = transferBody.getContent();
		}
		return bodyContent;
	}

	/**
	 *  采购入库单
	 * @param orders
	 */
	public PreInstorageVo transferFromOrderPurChase(AnntoOrderRequestBody order) {
		PreInstorageVo vo = new PreInstorageVo();
		MDHouseConfig mdHouseConfig = mdHouseConfigDao.loadByMdWarehouseCode(order.getPlant());
		InstorageBillPre instorageBillPre = new InstorageBillPre();
		instorageBillPre.setPreSendTm(order.getPlanArriveTime());
		instorageBillPre.setCustomerCode(WmsContants.CUSTOMER_MID);
		instorageBillPre.setInwarehouseCode(mdHouseConfig.getPyWarehouseCode());
		instorageBillPre.setOrderStatus(StatusEnums.PREORDER_STATUS_SEND.getStatus());
		instorageBillPre.setRemark(order.getRemark());
		instorageBillPre.setCustomerOrderNo(order.getCustOrdNo());
		instorageBillPre.setBillType(PYOrderType.PRE_ORDER.getType());
		instorageBillPre.setSubCustomerCode(order.getCustCustomerCode());
		instorageBillPre.setCusWarehouseCode(order.getPlant());
		instorageBillPre.setOldCusOrderNo(order.getOldOrdNo());
		instorageBillPre.setSourceOrdNo(order.getSourceOrdNo());
		instorageBillPre.setExpressNo(order.getExpressNo());

		List<InstorageBillBoxPre> boxes = new ArrayList<InstorageBillBoxPre>();
		InstorageBillBoxPre box = new InstorageBillBoxPre();
		box.setBoxCode(WmsContants.MID_BOX_CODE);
		boxes.add(box);
		List<InstorageBillItemPre> itemPres = new ArrayList<InstorageBillItemPre>();
		for (AnntoOrderDetail detail : order.getOrderDetails()) {
			// 订单下发的时候MD集团编码 对应派友的bar字段。
			EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, detail.getCustGoodsCode());
			if (goodsSku == null) {
				throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { detail.getCustGoodsCode() });
			}
			InstorageBillItemPre item = new InstorageBillItemPre();
			item.setLineNo(detail.getLineNo());
			item.setSkuCode(goodsSku.getSku());
			item.setGoodsNum(detail.getPlanQty());
			item.setBoxCode(WmsContants.MID_BOX_CODE);
			item.setErrorFlag(detail.getGoodsStatus());
			itemPres.add(item);
		}
		vo.setInstorageBillPre(instorageBillPre);
		vo.setInstorageBillBoxPres(boxes);
		vo.setInstorageBillItemPres(itemPres);
		return vo;
	}
	
	/**
	 *  盘点出入库
	 * @param orders
	 */
	public CheckInOrOut transferFromCheckInOrOut(AnntoOrderRequestBody order) {
		logger.info("美的盘点出入库消息接收解析XML：start");
		
		CheckInOrOut vo = new CheckInOrOut();
		MDHouseConfig mdHouseConfig = mdHouseConfigDao.loadByMdWarehouseCode(order.getPlant());
		
		vo.setOrderType(order.getOrderType());
		vo.setMdOrderNo(order.getCustOrdNo());
		vo.setCustCustomerCode(WmsContants.CUSTOMER_MID);
		vo.setWhcode(order.getPlant());
		vo.setWarehouseCode(mdHouseConfig.getPyWarehouseCode());
		vo.setCreateTime(new Date());
		
		List<CheckInOrOutItem> goodsItems = new ArrayList<CheckInOrOutItem>();
		for (AnntoOrderDetail detail : order.getOrderDetails()) {
			// 订单下发的时候MD集团编码 对应派友的bar字段。
			EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, detail.getCustGoodsCode());
			if (goodsSku == null) {
				throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { detail.getCustGoodsCode() });
			}
			CheckInOrOutItem goodsItem = new CheckInOrOutItem();
			goodsItem.setCustGoodsCode(detail.getCustGoodsCode());
			goodsItem.setLineNo(detail.getLineNo());
//			if(MDGoodsStatus.OTHERS.getType().equals(detail.getGoodsStatus())){
//				throw new PaiUException(ErrorCode.CHECK_GOODS_STATUS_ERROR, new String[] { detail.getCustGoodsCode() });
//			}
			goodsItem.setGoodsStatus(detail.getGoodsStatus());
			goodsItem.setPlanQty(detail.getPlanQty());
			goodsItem.setQty(detail.getPlanQty());
			goodsItems.add(goodsItem);
		}
		vo.setItemList(goodsItems);
		logger.info("美的盘点出入库消息接收解析XML：end");
		return vo;
	}
	
	public PreInstorageVo transferFromOrderBack(AnntoOrderRequestBody order) {
		PreInstorageVo vo = transferFromOrderPurChase(order);
		vo.getInstorageBillPre().setErrorFlg(MDGoodsStatus.OTHERS.getType());// 退货都是非正品
		return vo;
	}

	/**
	 * 拆分订单、每个SKU拆分为1单。赠品与任意非赠品合并为1单
	 * @param anntoOrder
	 * @return List<EdiOrder>
	 */
	public List<EdiOrder> transferFromOrderSale(AnntoOrderRequestBody anntoOrder) {
		List<EdiOrder> orders = new ArrayList<EdiOrder>();
		List<EdiOrderItem> notSellItems = new ArrayList<EdiOrderItem>();
		List<AnntoOrderDetail> orderDetails = anntoOrder.getOrderDetails();
		Collections.sort(orderDetails, new Comparator<AnntoOrderDetail>() {
			@Override
			public int compare(AnntoOrderDetail item1, AnntoOrderDetail item2) {
				return item1.getPrice() == null ? 1 : item2.getPrice() == null ? -1 : item2.getPrice().compareTo(item1.getPrice());
			}
		});
		//判断是否需要合并
		boolean mergeFlg = ifMerge(anntoOrder);
		if (mergeFlg) {
			EdiOrder order = transfer2EdiOrder(anntoOrder, mdHouseConfigDao.loadByMdWarehouseCode(anntoOrder.getPlant()), areaService.getTopAreaBy(anntoOrder.getProv(), anntoOrder.getCity()));
			List<EdiOrderItem> orderItems = new ArrayList<EdiOrderItem>();
			boolean priGtZero = false;
			for (int i = 0; i < orderDetails.size(); i++) {
				AnntoOrderDetail orderDetail = orderDetails.get(i);
				// 订单下发的时候MD集团编码 对应派友的bar字段。
				EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, orderDetail.getCustGoodsCode());
				if (goodsSku == null) {
					throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { orderDetail.getCustGoodsCode() });
				}
				EdiOrderItem item = transferFromOrderSale(orderDetail, goodsSku);
				item.setQty(orderDetail.getPlanQty());
				priGtZero = priGtZero || (item.getPri() != null && item.getPri() > 0);
				orderItems.add(item);
			}
			boolean invoiceFlg = order.getIsInvoice() && priGtZero;
			if (invoiceFlg && StringUtils.isBlank(order.getInvoiceTitle())) {
				throw new PaiUException(ErrorCode.INVOICE_INFO_ERROR, new String[] { order.getCustomerOrdeno() });
			}
			order.setIsInvoice(invoiceFlg);
			order.setSkulst(orderItems);
			orders.add(order);
		} else {
			for (int i = 0; i < orderDetails.size(); i++) {
				AnntoOrderDetail orderDetail = orderDetails.get(i);
				// 订单下发的时候MD集团编码 对应派友的bar字段。
				EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, orderDetail.getCustGoodsCode());
				if (goodsSku == null) {
					throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { orderDetail.getCustGoodsCode() });
				}
				if (string2Boolean(goodsSku.getSellFlg())) {
					for (int j = 0; j < orderDetail.getPlanQty(); j++) {// 按数量拆分
						EdiOrderItem item = transferFromOrderSale(orderDetail, goodsSku);
						List<EdiOrderItem> orderItems = new ArrayList<EdiOrderItem>();
						orderItems.add(item);
	
						EdiOrder order = transfer2EdiOrder(anntoOrder, mdHouseConfigDao.loadByMdWarehouseCode(anntoOrder.getPlant()), areaService.getTopAreaBy(anntoOrder.getProv(), anntoOrder.getCity()));
						boolean invoiceFlg = order.getIsInvoice() && (item.getPri() != null && item.getPri() > 0);
						if (invoiceFlg && StringUtils.isBlank(order.getInvoiceTitle())) {
							throw new PaiUException(ErrorCode.INVOICE_INFO_ERROR, new String[] { order.getCustomerOrdeno() });
						}
						order.setIsInvoice(invoiceFlg);
						orders.add(order);
						order.setSkulst(orderItems);
					}
				} else {
					EdiOrderItem item = transferFromOrderSale(orderDetail, goodsSku);
					item.setQty(orderDetail.getPlanQty());
					notSellItems.add(item);
				}
			}
			if (!orders.isEmpty() && !notSellItems.isEmpty()) {
				EdiOrder order = orders.get(0);
				order.setOrderType(StatusEnums.ORDER_TYPE_MULTIPLE.getStatus());
				order.getSkulst().addAll(notSellItems);
			} else if (orders.isEmpty() && !notSellItems.isEmpty()) {
				EdiOrder order = transfer2EdiOrder(anntoOrder, mdHouseConfigDao.loadByMdWarehouseCode(anntoOrder.getPlant()), areaService.getTopAreaBy(anntoOrder.getProv(), anntoOrder.getCity()));
				order.setOrderType((notSellItems.size() > 1 || notSellItems.get(0).getQty() > 1) ? StatusEnums.ORDER_TYPE_MULTIPLE.getStatus() : StatusEnums.ORDER_TYPE_SINGLE.getStatus());
				order.setIsInvoice(false);
				orders.add(order);
				order.setSkulst(notSellItems);
			}
		}
		return orders;
	}
	
	private boolean ifMerge(AnntoOrderRequestBody anntoOrder) {
		//买家自提不拆单
		if ("MJZT".equals(anntoOrder.getCarrierCode())) {
			return true;
		}
		boolean merge = false;
		for (AnntoOrderDetail orderDetail : anntoOrder.getOrderDetails()) {
			EdiGoodsSku goodsSku = ediGoodsSkuDao.findByCustomerCodeAndBar(WmsContants.CUSTOMER_MID, orderDetail.getCustGoodsCode());
			if (goodsSku == null) {
				throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] { orderDetail.getCustGoodsCode() });
			}
			List<OrderMergeConfig> config = orderMergeConfigDao.findConfig(WmsContants.CUSTOMER_MID, anntoOrder.getStoreCode(), goodsSku.getSku());
			if (!config.isEmpty()) {
				merge = true;
				break;
			}
		}
		return merge;
	}
	
	public EdiOrder transfer2EdiOrder(AnntoOrderRequestBody anntoOrder, MDHouseConfig mdHouseConfig, Area area) {
		Date now = new Date();
		EdiOrder order = new EdiOrder();
		// order.setLineNo(lineNo);
		order.setStatus(StatusEnums.ORDERS_STSTUA_PENDING.getStatus());
		order.setAdtime(now);
		order.setPatime(now);
		order.setOrderStatus(StatusEnums.ORDER_STATUS_OK.getStatus());
		order.setOrderType(StatusEnums.ORDER_TYPE_SINGLE.getStatus());
		order.setWarehouseCode(mdHouseConfig.getPyWarehouseCode());// 仓库编码
		order.setCusWarehouseCode(mdHouseConfig.getMdWarehouseCode());
		order.setCustomerOrdeno(anntoOrder.getCustOrdNo());// 订单号
		order.setFromno(anntoOrder.getSourceOrdNo());// 来源单号
		order.setOldOrdNo(anntoOrder.getOldOrdNo());// 原单号
		order.setRecena(anntoOrder.getContract());// 联系人
		order.setTeleph(anntoOrder.getContractPhone());// 联系电话
		order.setMobile(anntoOrder.getMobile());// 手机
		order.setPostco((StringUtils.isBlank(anntoOrder.getPlaceCode()) && area != null) ? area.getZipCode() : anntoOrder.getPlaceCode());// 邮编
		order.setProvna(anntoOrder.getProv());// 省
		order.setCityna(anntoOrder.getCity());// 市
		order.setDistna(anntoOrder.getDistrict());// 区
		order.setProvco(area != null ? area.getAreaCode() : null);
		order.setAddres(anntoOrder.getAddress());// 地址
		if (anntoOrder.getAddress() != null) {
			if (anntoOrder.getAddress().indexOf(anntoOrder.getProv()) > -1) {
				order.setAddres(anntoOrder.getAddress());
			} else if (anntoOrder.getAddress().indexOf("省") > -1) {
				order.setAddres(anntoOrder.getAddress());
			} else {
				order.setAddres(new StringBuilder().append(anntoOrder.getProv()).append(anntoOrder.getCity()).append(anntoOrder.getDistrict()).append(anntoOrder.getAddress()).toString());// 地址
			}
		}
		order.setIsInvoice(WmsContants.YES.equals(anntoOrder.getInvoiceFlag()));// 打印发票标示
		order.setInvoiceTitle(anntoOrder.getInvoiceTitle());// 发票抬头
		order.setInvoiceAmount(anntoOrder.getInvoiceAmount());// 发票金额
		order.setPodFlag(anntoOrder.getPodFlag());// 代收标示
		order.setPodAmount(anntoOrder.getPodAmount());// 代收金额
		order.setRemark(anntoOrder.getRemark());// 备注
		order.setCustomerCode(WmsContants.CUSTOMER_MID);// 客户编码
		order.setShopCode(anntoOrder.getStoreCode());// 店铺编码
		order.setShopna(anntoOrder.getStoreName());// 店铺名称
		order.setCrtime(now);
		order.setSubCustomerCode(anntoOrder.getCustCustomerCode());// 分销商代码
		order.setSubCustomerName(anntoOrder.getCustCustomerName());// 分销商名称
		if (string2Boolean(anntoOrder.getSpecCarrier())) {
			order.setOldCacode(anntoOrder.getCarrierCode());// 原始快递公司
			order.setCacode(dealCacode(anntoOrder.getCarrierCode()));// 快递公司
			order.setCaname(anntoOrder.getCarrierName());// 快递公司
		}
		order.setReceiver(anntoOrder.getReceiver());// 收货方代码(用于B2B结算)
		order.setReceiverName(anntoOrder.getReceiverName());// 收货方名称
		order.setPlanOutTime(anntoOrder.getPlanOutTime());// 计划发货时间
		order.setPlanArriveTime(anntoOrder.getPlanArriveTime());// 计划到货时间
		order.setSenderPhone(anntoOrder.getSenderPhone());// 发货人联系电话
		return order;
	}
	
	
	/**
	 * 转换快递编码
	 * @param orgCacode
	 * @return String
	 */
	private static String dealCacode(String orgCacode){
		return "EMS-JJKD".equals(orgCacode) ? "EMS" : "MIDEA".equals(orgCacode) ? null : orgCacode;
	}
	
	public EdiOrderItem transferFromOrderSale(AnntoOrderDetail orderDetail, EdiGoodsSku goodsSku) {
		EdiOrderItem item = new EdiOrderItem();
		item.setLineNo(orderDetail.getLineNo());
		item.setSellFlg(goodsSku.getSellFlg());
		item.setSku(goodsSku.getSku());
		item.setNam(orderDetail.getCustGoodsName());
		item.setCrtime(new Date());
		item.setQty(1);// 固定为1.
		item.setPri(orderDetail.getPrice());
		item.setAmo(orderDetail.getAmount());
		item.setVol(goodsSku.getVol());
		item.setDes("台");
		item.setOidStatus(orderDetail.getGoodsStatus());
		return item;
	}

	public static void main(String[] args) {

		EdiOrder order = new EdiOrder();
		order.setInvoiceTitle("发票打印");
		order.setOrdeno("1");

		InvoiceRequest request = new InvoiceRequest();
		request.setNormalType("0");
		request.setOpenType("1");
		request.setPrintAuto("0");

		EdiOrderItem item = new EdiOrderItem();
		item.setOrdeno(order.getOrdeno());
		item.setNam("测试商品");
		item.setSku("PSOOOOQSS");
		item.setPri(32D);
		item.setQty(1);
		item.setDes("台");
		item.setSellFlg("1");

		List<EdiOrderItem> items = new ArrayList<EdiOrderItem>();
		items.add(item);
		order.setOrderItems(items);
		System.out.println(buildInvoiceXml(order, request));

	}

	public static String buildInvoiceXml(EdiOrder order, InvoiceRequest request) {
		if (order == null)
			return null;
		StringBuilder xml = new StringBuilder();
		xml.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
		xml.append("<body>");
		xml.append("<root>");
		xml.append("<row id=\"1\">");
		xml.append("<main>");
		xml.append("<单据编号>");
		xml.append(order.getOrdeno());
		xml.append("</单据编号>");
		xml.append("<发票类型>");
		xml.append("c");
		xml.append("</发票类型>");
		xml.append("<购方名称>");
		xml.append(order.getInvoiceTitle());
		xml.append("</购方名称>");
		xml.append("<购方地址电话></购方地址电话>");
		xml.append("<备注>");
		xml.append(order.getBackupTaskCode());
		xml.append("    ");
		xml.append(order.getCustomerOrdeno());
		xml.append("    ");
		xml.append(order.getFromno());
		xml.append("    ");
		xml.append(order.getShopCode());
		xml.append("</备注>");
		xml.append("<开票日期>");
		xml.append(DateUtils.getYYYYMMDDDate());
		xml.append("</开票日期>");
		xml.append("<作废标志>");
		xml.append(request.getNormalType());
		xml.append("</作废标志>");
		xml.append("<开票标志>");
		xml.append(request.getOpenType());
		xml.append("</开票标志>");
		xml.append("<打印标志>");
		xml.append(request.getPrintAuto());
		xml.append("</打印标志>");
		xml.append("</main>");
		int index = 1;
		for (EdiOrderItem orderItem : order.getOrderItems()) {
			if (string2Boolean(orderItem.getSellFlg())) {
				xml.append(bulidDetailInvoice(orderItem, index++));
			}
		}
		xml.append("</row>").append("</root>").append("</body>");
		return xml.toString();
	}

	public static String bulidDetailInvoice(EdiOrderItem orderItem, int index) {
		StringBuilder xml = new StringBuilder();
		xml.append("<detail>");
		xml.append("<item id=\"").append(index).append("\">");
		xml.append("<单据编号>");
		xml.append(orderItem.getOrdeno());
		xml.append("</单据编号>");
		xml.append("<商品名称>");
		xml.append(orderItem.getNam());
		xml.append("</商品名称>");
		xml.append("<规格型号>");
		xml.append(orderItem.getSku());
		xml.append("</规格型号>");
		xml.append("<商品单位>");
		xml.append(orderItem.getDes());
		xml.append("</商品单位>");
		xml.append("<商品数量>");
		xml.append(orderItem.getQty());
		xml.append("</商品数量>");
		xml.append("<含税单价>");
		xml.append(orderItem.getPri());
		xml.append("</含税单价>");
		xml.append("<含税金额>");
		xml.append(BigDecimal.valueOf(orderItem.getQty()).multiply(BigDecimal.valueOf(orderItem.getPri())).doubleValue());
		xml.append("</含税金额>");
		xml.append("</item>");
		xml.append("</detail>");
		return xml.toString();
	}

	/**
	 * 构建退货入库的订单确认对象
	 * @return String
	 */
	public TransferData bulidConfirmBackData(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferData transferData = new TransferData();
		transferData.setTransferSubject(bulidSubject(documentType));
		transferData.setTransferBody(bulidConfirmBackBody(documentType, orderType, bill, countItems, sku2BarMap));
		return transferData;
	}

	/**
	 * 构建入库预约的订单确认对象
	 * @return String
	 */
	public TransferData bulidConfirmPurchaseData(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferData transferData = new TransferData();
		transferData.setTransferSubject(bulidSubject(documentType));
		transferData.setTransferBody(bulidConfirmPurchaseBody(documentType, orderType, bill, countItems, sku2BarMap));
		return transferData;
	}

	/**
	 * 构建销售出库的订单确认对象
	 * @return String
	 */
	public TransferData bulidConfirmSaleData(MDDocumentType documentType, MDOrderType orderType, List<WorkOrder> workOrders, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferData transferData = new TransferData();
		transferData.setTransferSubject(bulidSubject(documentType));
		transferData.setTransferBody(bulidConfirmSaleBody(documentType, orderType, workOrders, sku2BarMap));
		return transferData;
	}

	public TransferSubject bulidSubject(MDDocumentType documentType) {
		TransferSubject subject = new TransferSubject();
		subject.setDocumentType(documentType.getSubjectType());
		subject.setDataGenerationTime(new Date());
		subject.setReceiver(MDParam.MD_NAME);
		subject.setSender(MDParam.PAIU_NAME);
		subject.setVersion(MDParam.XML_VERSION);
		subject.setTransferFileID(genTransferFileId());
		return subject;
	}

	public TransferBody bulidConfirmSaleBody(MDDocumentType documentType, MDOrderType orderType, List<WorkOrder> workOrders, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferBody body = new TransferBody();
		body.setContent(bulidConfirmSaleContent(documentType, orderType, workOrders, sku2BarMap));
		return body;
	}

	public TransferBody bulidConfirmPurchaseBody(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferBody body = new TransferBody();
		body.setContent(bulidConfirmPurchaseContent(documentType, orderType, bill, countItems, sku2BarMap));
		return body;
	}

	public TransferBody bulidConfirmBackBody(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		TransferBody body = new TransferBody();
		body.setContent(bulidConfirmBackContent(documentType, orderType, bill, countItems, sku2BarMap));
		return body;
	}

	public TransferBodyContent bulidConfirmSaleContent(MDDocumentType documentType, MDOrderType orderType, List<WorkOrder> workOrders, Map<String, EdiGoodsSku> sku2BarMap) {
		switch (documentType) {
		case ORDERCONFIM:
			return bulidOrderConfirmContent(orderType, workOrders, sku2BarMap);
		}
		return null;
	}

	public TransferBodyContent bulidConfirmPurchaseContent(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		switch (documentType) {
		case ORDERCONFIM:
			return bulidConfirmPurchaseContent(orderType, bill, countItems, sku2BarMap);
		}
		return null;
	}

	public TransferBodyContent bulidConfirmBackContent(MDDocumentType documentType, MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		switch (documentType) {
		case ORDERCONFIM:
			return bulidConfirmBackContent(orderType, bill, countItems, sku2BarMap);
		}
		return null;
	}

	public TransferBodyContent bulidConfirmPurchaseContent(MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		InstorageCountItem item = countItems.get(0);
		OrderConfirmRequestBody content = new OrderConfirmRequestBody();
		content.setOrderType(orderType.getType());
		content.setWhCode(item.getWarehouseCode());
		if (bill.getPreBill() != null) {
			content.setCustOrdNo(bill.getPreBill().getCustomerOrderNo());
			content.setCustCustomerCode(bill.getPreBill().getSubCustomerCode());
			content.setWhCode(bill.getPreBill().getCusWarehouseCode());
		}
		// content.setCarrierCode(workOrder.getExpressCompany());
		// content.setExpressNo(expressNo.toString());
		// content.setWeight(weight);
		content.setProcessTime(new Date());
		// content.setInvoiceFlag(StringUtils.isBlank(item.getInvoiceNo()) ?
		// WmsContants.NO : WmsContants.YES);
		content.setConfigDetails(bulidConfirmPurchaseDetail(bill, countItems, sku2BarMap));
		return content;
	}

	public TransferBodyContent bulidConfirmBackContent(MDOrderType orderType, InstorageBill bill, List<InstorageCountItem> countItems, Map<String, EdiGoodsSku> sku2BarMap) {
		return bulidConfirmPurchaseContent(orderType, bill, countItems, sku2BarMap);
	}

	public TransferBodyContent bulidOrderConfirmContent(MDOrderType orderType, List<WorkOrder> workOrders, Map<String, EdiGoodsSku> sku2BarMap) {
		StringBuilder expressNo = new StringBuilder();
		Double weight = 0D;
		String invoiceFlg = WmsContants.NO;
		for (WorkOrder workOrder : workOrders) {
			expressNo.append(BlankUtil.isBlank(workOrder.getEbillNo(), workOrder.getExpressNo())).append(",");
			weight += Double.valueOf(workOrder.getWeight());
			if (!StringUtils.isBlank(workOrder.getInvoiceNo())) {
				invoiceFlg = WmsContants.YES;
			}
		}
		WorkOrder workOrder = workOrders.get(0);
		OrderConfirmRequestBody content = new OrderConfirmRequestBody();
		content.setOrderType(orderType.getType());
		content.setWhCode(workOrder.getOrder().getCusWarehouseCode());
		content.setCustOrdNo(workOrder.getCustomerOrderno());
		content.setCarrierCode(workOrder.getExpressCompany());
		content.setExpressNo(expressNo.deleteCharAt(expressNo.length() - 1).toString());
		content.setCustCustomerCode(workOrder.getOrder().getSubCustomerCode());
		content.setWeight(weight);
		content.setProcessTime(new Date());
		content.setInvoiceFlag(invoiceFlg);
		content.setConfigDetails(bulidOrderDetail(workOrders, sku2BarMap));
		return content;
	}

	public List<OrderConfirmDetail> bulidOrderDetail(List<WorkOrder> workOrders, Map<String, EdiGoodsSku> sku2BarMap) {
		List<OrderConfirmDetail> details = new ArrayList<OrderConfirmDetail>();
		Map<String, OrderConfirmDetail> detailMap = new HashMap<String, OrderConfirmDetail>();// sku+行号
		for (WorkOrder workOrder : workOrders) {
			EdiOrder ediOrder = workOrder.getOrder();
			for (int i = 0; i < ediOrder.getOrderItems().size(); i++) {
				EdiOrderItem item = ediOrder.getOrderItems().get(i);
				String key = new StringBuilder().append(item.getSku()).append("_").append(item.getLineNo()).toString();
				OrderConfirmDetail detail = detailMap.get(key);
				if (detail == null) {
					detail = new OrderConfirmDetail();
					detail.setLineNo(item.getLineNo());
					detail.setCustGoodsCode(sku2BarMap.get(item.getSku()).getBar());
					detail.setPlanQty(item.getQty());
					detail.setQty(item.getQty());
					detail.setGoodsStatus(MDGoodsStatus.NORMAL.getType());
					detail.setCarrierCode(workOrder.getExpressCompany());//
					detail.setExpressNo(BlankUtil.isBlank(workOrder.getEbillNo(), workOrder.getExpressNo()));
					detail.setVolume(StringUtils.isBlank(item.getVol()) ? null : Double.valueOf(item.getVol()));
					detail.setPackageWeight(workOrder.getWeight());
					detail.setInvoiceNo(workOrder.getInvoiceNo());
					detail.setInvoiceBy(workOrder.getInvoiceOperate());
					detail.setInvoiceTime(new Date());
					details.add(detail);
					detailMap.put(key, detail);
				} else {
					detail.setExpressNo(new StringBuilder().append(detail.getExpressNo()).append(",").append(BlankUtil.isBlank(workOrder.getEbillNo(), workOrder.getExpressNo())).toString());
					detail.setCarrierCode(new StringBuilder().append(detail.getCarrierCode()).append(",").append(workOrder.getExpressCompany()).toString());
					if ("1".equals(workOrder.getNeedInvoice())) {
						detail.setInvoiceNo(new StringBuilder().append(detail.getInvoiceNo()).append(",").append(workOrder.getInvoiceNo()).toString());
					}
					detail.setPlanQty(detail.getPlanQty() + item.getQty());
					detail.setQty(detail.getQty() + item.getQty());
					if (!StringUtils.isBlank(item.getVol())) {
						detail.setVolume((detail.getVolume() == null ? 0D : detail.getVolume()) + Double.valueOf(item.getVol()));
					}
					detail.setPackageWeight(detail.getPackageWeight() + workOrder.getWeight());

				}
			}
		}
		return details;
	}

	public List<OrderConfirmDetail> bulidConfirmPurchaseDetail(InstorageBill bill, List<InstorageCountItem> items, Map<String, EdiGoodsSku> sku2BarMap) {
		Map<String, Integer> pickedMap = EdiOrderUtil.countByUp(items);
		InstorageBillPre preBill = bill.getPreBill();
		List<InstorageBillItemPre> billItems = preBill.getBillItem();
		List<OrderConfirmDetail> details = new ArrayList<OrderConfirmDetail>();
		for (InstorageBillItemPre instorageBillItemPre : billItems) {
			OrderConfirmDetail detail = new OrderConfirmDetail();
			detail.setLineNo(instorageBillItemPre.getLineNo());
			detail.setCustGoodsCode(sku2BarMap.get(instorageBillItemPre.getSkuCode()).getBar());
			detail.setPlanQty(instorageBillItemPre.getGoodsNum());
			detail.setQty(decrementSkuQty(pickedMap, instorageBillItemPre.getSkuCode(), instorageBillItemPre.getGoodsNum()));
			detail.setGoodsStatus(instorageBillItemPre.getErrorFlag());
			// detail.setCarrier_code(workOrder.getExpressCompany());//
			// detail.setExpressNo(BlankUtil.isBlank(workOrder.getEbillNo(),
			// workOrder.getExpressNo()));
			// detail.setVolume(Double.valueOf(item.getVol()));
			// detail.setPackageWeight(workOrder.getWeight());
			// detail.setInvoicePlace(MDParam.INVOICE_PLACE);
			// detail.setInvoiceNo(workOrder.getInvoiceNo());
			// detail.setInvoiceBy(MDParam.INVOICE_BY);
			// detail.setInvoiceTime(new Date());
			details.add(detail);
		}
		if (!pickedMap.isEmpty()) {
			logger.error(new StringBuilder().append("notice======planQty is not match pickedQty====").append(bill.getBillCode()).toString());
		}
		return details;
	}

	public static Integer decrementSkuQty(Map<String, Integer> pickedMap, String sku, Integer planQty) {
		Integer pickedQty = pickedMap.get(sku);
		if (pickedQty != null) {
			int leftQty = pickedQty - planQty;
			if (leftQty == 0) {
				pickedMap.remove(sku);
			} else {
				pickedMap.put(sku, leftQty);
			}
			return Math.min(pickedQty, planQty);
		}
		return 0;
	}

	public static String boolean2String(boolean b) {
		return b ? "1" : "0";
	}

	public static boolean string2Boolean(String s) {
		return WmsContants.YES.equalsIgnoreCase(s) || "1".equals(s) ? true : false;
	}

	public static String genTransferFileId() {
		return TMSTransportRule.generateWaybillNo();
	}

}